package com.zte.cl.service.impl;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;

import com.zte.cl.repository.ChannelRepository;
import com.zte.cl.repository.CompanyBaseInfoRepository;
import com.zte.cl.repository.CompanySystemRepository;
import com.zte.cl.repository.UserInfoRepository;
import com.zte.cl.service.PushService;
import com.zte.cl.thread.PushMsgThread;
import com.zte.cl.utils.ConstantUtil;
import com.zte.cl.utils.StringUtil;

@Service("pushService")
public class PushServiceImpl implements PushService {

	private static final Log log = LogFactory.getLog(PushServiceImpl.class);
	
	@Resource
	private CompanyBaseInfoRepository companyBaseInfoRepository;
	
	@Resource
	private UserInfoRepository userInfoRepository;
	
	@Resource
	private ChannelRepository channelRepository;
	
	@Resource
	private CompanySystemRepository companySystemRepository;
	
	@Resource(name = "pushThreadPool")
	private ThreadPoolTaskExecutor pushThreadPool;
	
	@Override
	public void pushMsg(Map<String, String> msg) throws Exception {
		if(ConstantUtil.NEWS_PUSH_DO) {
			String pushRange = ConstantUtil.NEWS_PUSH_RANGE;
			String[] receiverCode = ConstantUtil.NEWS_PUSH_RECEIVER_CODE.split(",");
			String publicAccount = ConstantUtil.NEWS_PUSH_DEFAULT_PUBLIC_ACCOUNT;
			
			if(StringUtil.equals(pushRange, "system", false)) {
				pushMsgBySystem(publicAccount, receiverCode, msg);
			} else if(StringUtil.equals(pushRange, "channel", false)) {
				Integer[] channelIds = new Integer[receiverCode.length];
				for(int i = 0; i < receiverCode.length; i++) {
					channelIds[i] = Integer.parseInt(receiverCode[i]);
					pushMsg(publicAccount, channelIds, msg);
				}
			} else if(StringUtil.equals(pushRange, "company", false)) {
				pushMsg(publicAccount, receiverCode, msg);
			}
		} else {
			log.info("msg[{title:"+msg.get("title")+", content:"+msg.get("content")+"}]");
		}
		
	}

	@Override
	public void pushMsg(String publicAccount, String[] companyIds, Map<String, String> msg) throws Exception {
		List<String> companyIdList = Arrays.asList(companyIds);
		log.info("一共需要向" + companyIdList.size() + "个公司推送信息!");
		int lengthLimit = ConstantUtil.NEWS_PUSH_THREAD_COMPANY_MAX_COUNT;
		if(companyIdList.size() > lengthLimit) {
			log.info("超出" + lengthLimit +"条记录, 开始分割list, 使用多线程推送消息");
			int listCount = companyIdList.size() / lengthLimit + 1;
			log.info("一共需要分割出" + listCount + "个list");
			for(int i = 0; i < listCount; i++) {
				log.info("开始处理第" + (i+1) + "个list!");
				List<String> tempList = null;
				if(i == listCount - 1) {
					tempList = new ArrayList<String>(companyIdList.subList(lengthLimit * i, companyIdList.size()));
				} else {
					tempList = new ArrayList<String>(companyIdList.subList(lengthLimit * i, lengthLimit * (i+1)));
				}
				pushThreadPool.execute(new PushMsgThread(publicAccount, tempList, msg));
			}
		} else {
			log.info("没有超出" + lengthLimit + "条记录, 使用单线程推送消息!");
			pushThreadPool.execute(new PushMsgThread(publicAccount, companyIdList, msg));
		}
	}

	@Override
	public void pushMsg(String publicAccount, Integer[] channelIds, Map<String, String> msg) throws Exception {
		String[] companyIds = companyBaseInfoRepository.findCompanyIdByChannelIdIn(channelIds);
		if(companyIds.length > 0) {
			pushMsg(publicAccount, companyIds, msg);
		} else {
			log.warn("没有获取到合适的公司列表, channelIds:" + channelIds);
		}
	}
	
	@Override
	public void pushMsgBySystem(String publicAccount, String[] systemCodes, Map<String, String> msg) throws Exception {
		String[] companyIds = companySystemRepository.findCompanyCodeBySystemCodeIn(systemCodes);
		if(companyIds.length > 0) {
			pushMsg(publicAccount, companyIds, msg);
		} else {
			log.warn("没有获取到合适的公司列表, systemCodes:" + systemCodes);
		}
		
	}
	
}
